本篇會分享從生成 APK/AAB、設置應用、測試應用到上架 Play Store 的過程。
Keystore 憑證用於保存加密的金鑰。為驗證開發者身份,應用需要使用 keystore 進行數位簽署。只有擁有憑證私鑰的人才能創建、更新應用,所以必須好好保存。
注意:如果丟失上架應用的 keystore 密碼、私鑰的相關信息,那原本的應用就無法繼續更新,只能創建新的應用或者向 google 申請換成新的 key。
keytool -genkeypair -v -storetype PKCS12 -keystore ${KEY_NAME}.keystore -alias ${KEY_ALIAS} -keyalg RSA -keysize 2048 -validity 10000
keytool -genkeypair -v -storetype PKCS12 -keystore pokedex.keystore -alias pokedex -keyalg RSA -keysize 2048 -validity 10000
- keytool: Java 中用於管理金鑰和憑證的命令工具
- -genkeypair: 生成一個金鑰組,即公鑰和私鑰
- -storetype PKCS12: 金鑰的類型為 PKCS12
- -keystore {KEY_NAME.keystore}: 金鑰檔案名稱為
${KEY_NAME}.keystore- -alias {KEY_ALIAS}: keystore 的別名為
${KEY_ALIAS}- -keyalg RSA: 指定產生金鑰組使用 RSA 演算法為
- -keysize 2048: 指定產生的每一個金鑰的大小為2048位元,金鑰大小至少為 112 位元,建議設為 2048 位元。
- -validity 10000: 生成的憑證有效期為 10000 天,即憑證將在 10000 天後過期

<KEY_NAME>.keystore 在輸入指令的路徑: 
注意:記得將
.keystore加進.gitignore中,不要上傳。
<KEYSTORE_NAME>.keystore 放到 android/app 下。keystore.properties 將 keystore 變數存在裡面:
STORE_FILE=KEYSTORE_NAME.keystore
KEY_ALIAS=KEYSTORE_ALIAS
STORE_PASSWORD=******
KEY_PASSWORD=******
STORE_PASSWORD 就是剛剛生成密鑰對時輸入的密碼,KEY_PASSWORD 會和 STORE_PASSWORD 一樣。 
注意:記得將
keystore.properties加進.gitignore。
在 android/app/build.gradle 添加以下內容:
buildTypes.release.sigingConfig 改成 signingConfigs.release
// android/app/build.gradle
...
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('keystore.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
    ...
    defaultConfig { ... }
    signingConfigs {
        ...
        release {
            if (keystoreProperties['STORE_FILE']) {
                storeFile file(keystoreProperties['STORE_FILE'])
                storePassword keystoreProperties['STORE_PASSWORD']
                keyAlias keystoreProperties['KEY_ALIAS']
                keyPassword keystoreProperties['KEY_PASSWORD']
            }
        }
    }
    buildTypes {
        release {
            ...
            signingConfig signingConfigs.release
        }
    }
}
...

只需要將 .jks 或者 .p12 上傳到 Expo project 的 credentials 中,Expo 會自動執行 Android 和 iOS 應用程式的簽署過程。
Project - Credentials - Get Started (或 +Application Identifier)

你需要提供:
android/app/src/main/AndroidManifest.xml 中的 package)

記得修改應用的版本號 versionName, versionCode,上傳到 Play Store 不能有重複的 versionCode,每一次上傳新版本記得都要將 versionCode + 1
android/app/build.gradle
android {
	...
	defaultConfig {
		...
		versionCode 1
		versionName "1.0.0"
	}
}
應用上架前的準備工作: https://ithelp.ithome.com.tw/articles/10329076
使用以下指令開始打包:
android/app/build/outputs/apk/release
assembledebug
cd android && ./gradlew assembleRelease && cd ..
android/app/build/outputs/bundle/release
cd android && ./gradlew bundleRelease && cd ..
有時候打包發生未知的錯誤可以
./gradlew clean清除 build 資料夾後再重新打包
如果打包時出現下面這個錯誤就代表 java 版本和 gradle 的不適配
* What went wrong:
Could not open settings generic class cache for settings file '/android/settings.gradle' (Users/.gradle/caches/8.0.1/scripts/xxxxxxxxx).
> BUG! exception in phase 'semantic analysis' in source unit '_BuildScript_' Unsupported class file major version 64

官方有提供 gradle 和 java 版本對應表
https://docs.gradle.org/current/userguide/compatibility.html#java

像我是 java 20 就應該對應 gradle 8.1,所以我使用 8.0.1 會因為版本過低而失敗。
android/gradle/wrapper/gradle-wrapper.properties 可以查看 gradle 版本java -version 可以查看 java 版本

因此將 android/gradle/wrapper/gradle-wrapper.properties 的 distributionUrl 改成 8.1 的連結即可
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-all.zip
查看 gradle 版本: https://services.gradle.org/distributions/
Execution failed for task ':app:compileReleaseJavaWithJavac'.
我自己遇到這個 error 是因為 AndroidManifest.xml 的  package 與 build.gradle 中的 applicationId 不一致,改成一致之後就解決了。
在把 release 版本的 AAB 提交到 Play Store 之前,你可以先測試一下應用是否能正常使用:
npx react-native run-android --variant=release
注意:
--variant=release只能在你完成了上面的簽署配置之後才可以使用。- 在 debug 和 release 版本間來回切換安裝時可能會導致簽署不匹配,需要先卸載前一個版本再安裝一次。
如要建立 play console 帳戶需要 $25 USD 的註冊費 (僅須支付一次)。
在 Play Console 建立 developer 帳戶,選擇帳戶類型:

後面步驟按照提示走即可,註冊完需要上傳證件照片驗證身份後才能發布應用(包括內部測試)


可以接受駕照、護照、身分證、居留證。

驗證的過程大概需要 1~2 個工作日,我自己是等了 1 天。
在上架之前可以先進行內部測試,內部測試不需要通過 Google 審核,並且可以將應用分享給 100 位內部測試人員,藉此找出問題並在初期取得意見回饋。
首先建立一個新的應用程式

就算只是要在內部測試還是得把一系列設定全部設定完,這邊我就不一張一張截圖要不然實在是太多了...各位按照步驟一步一步來吧

如果需要隱私權政策 URL,可以直接使用工具生成:https://app.privacypolicies.com/


設置應用商店資料:

這些圖像是必傳的:



左側菜單找到「內部測試」點擊「選取測試人員」:

將要測試的 email 添加進測試名單,多個 Email 之間用逗號, 隔開,然後記得按 Enter 新增:

選取好測試的人員之後按下「儲存」

接著「建立新版本」

點擊「選擇簽署金鑰」

這邊我建議是使用 Google 產生的金鑰

上傳 AAB 以及填寫版本資料:

在這邊你能看到與版本相關的錯誤、警告,如果有錯誤的話必須先解決。

一切設置完成之後在 設定 - 內部應用程式分享 將管理測試人員選為「限制存取電子郵件名單」,然後選擇下載者的清單:


如果你的應用需要登入後才能使用部分功能,需要在「測試 - 正式發布前測試報告 - 設定」中設置「提供測試帳戶憑證」

還有設置 deep link, 多語系

接著回到 內部測試 - 測試人數 下面有一個「複製連結」的按鈕,這個連結就是下載內部應用程式的連結,會導向 Play Store 下載內部測試應用:



如果想刪除錯誤或不用的 app bundle 版本可以在「應用程式套件探索工具」找到要刪除的版本右側點進去

右側有一個「刪除 app bundle」,刪除即可

所有測試和設置都完成後,上架 Play Store 只缺需要提交正式版本以及提交送審即可。

測試 - 正式發布前測試報告 - 詳細資訊 這邊可以看到應用測試的結果,分穩定性、成效、無障礙、螢幕截圖、安全性,Google 會為你的應用在不同設備上進行測試並提供相關建議,你可以調整後再上架應用。

發布總覽 - 將 N 項變更送審 即可提交應用審核,審核通過後應用就會上架 Play Store,第一次送審的時間最長約 7 天,後續送審就不需要這麼久了。
